---
title: .autoDispose
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

A common use-case when using providers is to want to destroy the state of a provider
when it is no-longer used.

There are multiple reasons for doing such, such as:

- When using Firebase, to close the connection and avoid unnecessary cost
- To reset the state when the user leaves a screen and re-enters it.

Providers comes with a built-in support for such use-case, through the `.autoDispose`
modifier.

## Usage

To tell Riverpod to destroy the state of a provider when it is no-longer used,
simply append `.autoDispose` to your provider:

```dart
final userProvider = StreamProvider.autoDispose<User>((ref) {

})
```

That's it. Now, the state of `userProvider` will automatically be destroyed
when it is no-longer used.

Note how the generic parameters are passed after `autoDispose` instead of before –
`autoDispose` is not a named constructor.

:::note
You can combine `.autoDispose` with other modifiers if you need to:

```dart
final userProvider = StreamProvider.autoDispose.family<User, String>((ref, id) {

})
```

:::

### ref.maintainState

Marking a provider with `autoDispose` also adds an extra property on `ref`: `maintainState`.

The `maintainState` property is a boolean (`false` by default) that allows
the provider to tell Riverpod if the state of the provider should be preserved
even if no-longer listened.

A use-case would be to set this flag to `true` after an HTTP request have
completed:

```dart
final myProvider = FutureProvider.autoDispose((ref) async {
  final response = await dio.get(...);
  ref.maintainState = true;
  return response;
});
```

This way, if the request failed and the user leaves the screen then re-enters
it, then the request will be performed again.
But if the request completed successfuly, the state will be preserved
and re-entering the screen will not trigger a new request.

## Example: Cancelling HTTP requests when no-longer used

The `autoDispose` modifier could be combined with [FutureProvider] and `ref.onDispose`
to easily cancel HTTP requests when they are no-longer needed.

The goal is:

- Start an HTTP request when the user enters a screen
- if the user leaves the screen before the request completed, cancels the HTTP request
- if the request succeeded, leaving and re-entering the screen does not start a new request

In code, this would be:

```dart
final myProvider = FutureProvider.autoDispose((ref) async {
  // An object from package:dio that allows cancelling http requests
  final cancelToken = CancelToken();
  // When the provider is destroyed, cancel the http request
  ref.onDispose(() => cancelToken.cancel());

  // Fetch our data and pass our `cancelToken` for cancellation to work
  final response = await dio.get('path', cancelToken: cancelToken);
  // If the request completed successfully, keep the state
  ref.maintainState = true;
  return response;
});
```

## The argument type 'AutoDisposeProvider' can't be assigned to the parameter type 'AlwaysAliveProviderBase'

When using `.autoDispose`, you may find yourself in a situation where your
application does not compile with an error similar to:

> The argument type 'AutoDisposeProvider' can't be assigned to the parameter
> type 'AlwaysAliveProviderBase'

Don't worry! This error is voluntary. It happens because you most likely
have a bug:

You tried to listen to a provider marked with `.autoDispose` in a provider that
is **not** marked with `.autoDispose`, such as:

```dart
final firstProvider = Provider.autoDispose((ref) => 0);

final secondProvider = Provider((ref) {
  // The argument type 'AutoDisposeProvider<int>' can't be assigned to the
  // parameter type 'AlwaysAliveProviderBase<Object, Null>'
  ref.watch(firstProvider);
})
```

This is undesired, as it would cause `firstProvider` to never be disposed.

To fix, consider marking `secondProvider` with `.autoDispose` too:

```dart
final firstProvider = Provider.autoDispose((ref) => 0);

final secondProvider = Provider.autoDispose((ref) {
  ref.watch(firstProvider);
})
```

[provider]: https://pub.dev/documentation/riverpod/latest/all/Provider-class.html
[futureprovider]: https://pub.dev/documentation/riverpod/latest/all/FutureProvider-class.html
